#include "main.h"

static struct shm_param para;
int main() {
    INIT_LIST_HEAD(&head.list);
    struct mb_node_list nodes[MAX_NODES];
    FILE *fp = fopen("../config.json", "r");
    if (fp == NULL) {
        printf("Error opening file.\n");
        return 1;
    }
    char buffer[MAX_BUF_SIZE];
    memset(buffer, 0, MAX_BUF_SIZE);
    fread(buffer, 1, MAX_BUF_SIZE, fp);
    fclose(fp);
    cJSON *sproot = cJSON_Parse(buffer);
	cJSON *modbus2 = cJSON_GetObjectItem(sproot, "modbus");
    cJSON *data = cJSON_GetObjectItem(modbus2, "data");
    int num_nodes = cJSON_GetArraySize(data);
	printf("num_nodes = %d\n",num_nodes);
    cJSON *spitem = NULL;
    for (int i = 0; i < num_nodes; i++) {
        spitem = cJSON_GetArrayItem(data, i);
        nodes[i].node.key = cJSON_GetObjectItem(spitem, "key")->valueint;
        strcpy(nodes[i].node.name, cJSON_GetObjectItem(spitem, "name")->valuestring);
        nodes[i].node.type = cJSON_GetObjectItem(spitem, "type")->valueint;
        nodes[i].node.addr = cJSON_GetObjectItem(spitem, "addr")->valueint;
        list_add(&nodes[i].list, &head.list);
    }
    cJSON* mb_dev = cJSON_GetObjectItem(sproot,"mb_dev");
    modbus_t *modbus;
    modbus = modbus_new_tcp(cJSON_GetObjectItem(mb_dev,"addr")->valuestring, cJSON_GetObjectItem(mb_dev,"port")->valueint);
    cJSON_Delete(sproot);
    modbus_set_slave(modbus, 1);
    modbus_connect(modbus);
    pthread_t tidsend, tidget;
    pthread_create(&tidget, NULL, thread_getmsg, (void *)modbus);
    pthread_create(&tidsend, NULL, thread_sendmsg, (void *)modbus);

    pthread_join(tidsend, NULL);
    pthread_join(tidget, NULL);
    modbus_close(modbus);
    modbus_free(modbus);

    return 0;
}

void *thread_getmsg(void *arg) {
    struct msgvalue msg;
    while (1) {
        modbus_t *modbus = (modbus_t *)arg;
        msg_queue_recv("msg", &msg, sizeof(msg), RECV_MSG, IPC_WAIT);
        printf("获取成功 id : %d:%d\n", msg.key, msg.status);
        struct list_head *pos;
        struct mb_node_list *item;
        list_for_each_prev(pos, &head.list) {
            item = list_entry(pos, struct mb_node_list, list);
            if (item->node.key == msg.key)
                modbus_write_bit(modbus, item->node.addr - BITADDR, msg.status);
        }
    }
}

void *thread_sendmsg(void *arg) {
    data_t d;
    static int i = 0;
    int ret = -1;
    shm_init(&para, "shm", 4);
    char *addr = (char *)shm_getaddr(&para);
    if (addr == NULL) {
        printf("shm_getaddr err\n");
        return (void *)-1;
    }
    modbus_t *modbus = (modbus_t *)arg;
    uint16 z, x;

    struct list_head *pos;
    struct mb_node_list *item;
   
    while (1) {
        modbus_read_bits(modbus, 0, 4, (void *)&d);
        modbus_read_registers(modbus, 0, 1, &z);
        modbus_read_registers(modbus, 1, 1, &x);
        d.co2 = z + x * 0.01;
        modbus_read_registers(modbus, 2, 1, &z);
        modbus_read_registers(modbus, 3, 1, &x);
        d.h2o = z + x * 0.01;

        int len = *(int *)addr;
         printf("%p\n", addr);
        struct std_node *temp = (void *)addr + sizeof(int) + 4 * sizeof(struct std_node);
         printf("%p\n", temp);
        list_for_each_prev(pos, &head.list) {
            item = list_entry(pos, struct mb_node_list, list);
            if (item->node.type == 0) {
                temp->new_val.b_val = *(bool *)((void *)&d + item->node.addr - BITADDR);
                 printf("new_val.b_val = %d\n", temp->new_val.b_val);
            } else if (item->node.type == 2) {
                temp->new_val.f_val = *(float *)((void *)&d + 4 + item->node.addr - REGISTER);
                 printf("new_val.f_val = %.2f\n", temp->new_val.f_val);
            }
            temp++;
        }
        sleep(3);
    }
}
